﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using DatingSoonMVC2008.Library;
using System.Diagnostics;
using System.Transactions;

namespace DatingSoonMVC2008.Models
{
    public class Facade : DatingSoonMVC2008.Models.IFacade
    {
        DatingSoonDBDataContext db;
        public Facade(DatingSoonDBDataContext db)
        {
            this.db = db;
        }

        public bool CheckCredentials(string name, string password)
        {
            var user = from zooUsers in db.ZooUsers
                       where zooUsers.NickName == name &&
                       zooUsers.Password == password
                       select zooUsers;

            return (user.FirstOrDefault<ZooUser>() != null);
        }

        #region IFacade Members


        public System.Collections.Specialized.StringDictionary CreateDictionary(string language)
        {
            //Preconditions
            Debug.Assert(language != null, "Precondition assertion failed, ZooModel.CreateDictionary language was null");
            Debug.Assert(language.Length > 1, "Precondition assertion failed, ZooModel.CreateDictionary language length was <2");

            //Implementation
            System.Collections.Specialized.StringDictionary stringDico = new System.Collections.Specialized.StringDictionary();

            var query = from Dictionary d in db.Dictionaries
                        select d;

            IDbCommand command = this.db.GetCommand(query as IQueryable);
            command.Connection = this.db.Connection;
            if (command.Connection.State != ConnectionState.Open)
                command.Connection.Open();
            IDataReader rdr = command.ExecuteReader(CommandBehavior.CloseConnection);

            try
            {
                while (rdr.Read())
                {
                    stringDico.Add(
                        rdr["DictionaryKey"].ToString().ToLower().Trim(),
                        rdr[language].ToString());
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                rdr.Close();
                command.Connection.Close();
            }

            //Postconditions
            Debug.Assert(stringDico.Count > 0, "PostCondition assertion failed, ZooModel.CreateDictionary stringDico was empty");

            return stringDico;
        }

        public ListItemCollection GetCountryList(Dico currentDictionary)
        {
            //Preconditions
            Debug.Assert(currentDictionary != null, "Preconditionerror, ZooModel.GetCountryList assert false, currentDictionary is Null");

            //Implementation
            System.Web.UI.WebControls.ListItemCollection returnValue = new System.Web.UI.WebControls.ListItemCollection();
            var countrys = from Country c in db.Countries
                           select c;

            foreach (Country country in countrys)
            {
                returnValue.Add(new ListItem(currentDictionary[country.CountryName], country.CountryID.ToString()));
            }

            //PostConditions
            Debug.Assert(returnValue.Count > 0, "Postcondition, GetCountryList return value is empty!");

            return returnValue;
        }

        public ListItemCollection GetRegionList(string countryValue, Dico currentDictionary)
        {
            //Preconditions 
            int countryID;
            Debug.Assert(int.TryParse(countryValue, out countryID), "Precondition error, ZooModel.GetRegionList assert false countryValue could not be parsed as int");
            Debug.Assert(currentDictionary != null, "Preconditionerror, ZooModel.GetCountryList assert false, currentDictionary is Null");

            //Implementation
            System.Web.UI.WebControls.ListItemCollection returnValue = new System.Web.UI.WebControls.ListItemCollection();
            var regions = from Region r in db.Regions
                          select r;

            foreach (Region region in regions)
            {
                returnValue.Add(new ListItem(currentDictionary[region.RegionName], region.RegionID.ToString()));
            }

            //PostConditions
            Debug.Assert(returnValue.Count > 0, "Postcondition assertion failed, ZooModel.GetRegionist returnValue was empty");
            return returnValue;
        }

        public void Register(string language, string nickName, string emailAddress, char gender, char seeking, int countryID, int regionID, DateTime bornDate, string city, string description, string password, bool emailOptin, byte[] pictureContent, IPictureStorage pictureStorage)
        {
            //Precondition
            Debug.Assert(!Utility.IsEmpty(language), "ZooModel Register precondition assertion failed: language was empty!");
            Debug.Assert(!Utility.IsEmpty(nickName), "ZooModel Register precondition assertion failed: nickName was empty!");
            Debug.Assert(!Utility.IsEmpty(emailAddress), "ZooModel Register precondition assertion failed: emailAddress was empty!");
            Debug.Assert(!Utility.IsEmpty(gender.ToString()), "ZooModel Register precondition assertion failed: gender was empty!");
            Debug.Assert(!Utility.IsEmpty(seeking.ToString()), "ZooModel Register precondition assertion failed: seeking was empty!");
            Debug.Assert(!Utility.IsNull(bornDate), "ZooModel Register precondition assertion failed: bornDate was null!");
            Debug.Assert(!Utility.IsEmpty(city), "ZooModel Register precondition assertion failed: city was empty!");
            Debug.Assert(!Utility.IsEmpty(description), "ZooModel Register precondition assertion failed: description was empty!");
            Debug.Assert(!Utility.IsEmpty(password), "ZooModel Register precondition assertion failed: password was empty!");
            Debug.Assert(pictureContent.Length > 0, "PictureContent Length was 0, image was not present!");

            using (TransactionScope tran = new TransactionScope(TransactionScopeOption.RequiresNew))
            {
                ZooUser user = new ZooUser();
                Picture registrationPicture = new Picture();
                try
                {
                    user.BornDate = bornDate;
                    user.City = city;
                    user.CountryID = countryID;
                    user.Description = description;
                    user.EmailAddress = emailAddress;
                    user.EmailOptin = emailOptin;
                    user.Gender = gender;
                    user.LastLogin = DateTime.Now;
                    user.NickName = nickName;
                    user.Online = true;
                    user.RegionID = regionID;
                    user.Password = password;
                    user.Seeking = seeking;
                    user.UserLanguage = language;
                    user.RegistrationDate = DateTime.Now.AddDays(-100);
                    db.ZooUsers.InsertOnSubmit(user);

                    registrationPicture.PictureIndex = 0;
                    registrationPicture.PictureTitle = user.NickName;
                    registrationPicture.PictureDescription = "";
                    registrationPicture.ZooUser = user;

                    db.SubmitChanges();

                    int imageHeight = Convert.ToInt32(ConfigurationManager.AppSettings["ImageHeight"]);
                    pictureStorage.Save(pictureContent, registrationPicture.PictureID, imageHeight);
                    tran.Complete();
                }
                catch (Exception ex)
                {
                    //Cleanup
                    pictureStorage.Delete(registrationPicture.PictureID);
                    tran.Dispose();
                    throw;
                }
                //PostCondition
                Debug.Assert(user.UserID > 0, "ZooModel.Register postcondition assertion failed: user was not saved!");
            }

        }

        public bool UserExist(string nickName)
        {
            var users = from ZooUser u in db.ZooUsers
                        where u.NickName == nickName
                        select u;

            return (users.FirstOrDefault() != null);
        }

        public IdentityCard[] GetNewUsers(string language)
        {
            throw new NotImplementedException();
        }

        public IdentityCard GetUserDetail(int userID)
        {
            throw new NotImplementedException();
        }

        public IdentityCard[] FindUsers(string[] languages, int ageMax, int ageMin, string city, string gender, int countryID, int regionID, string seeking)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
